package cn.edu.nit.sys.service.impl;

import cn.edu.nit.sys.entity.Subject;
import cn.edu.nit.sys.mapper.SubjectMapper;
import cn.edu.nit.sys.service.SubjectService;
import cn.edu.nit.sys.timer.UpdateSignDataTask;
import cn.edu.nit.sys.utils.R;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;

/**
 * @Author xiaobai
 * @Date 2023/3/19 15:02
 * @Version 1.0.0
 */
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {

    @Autowired
    private Scheduler scheduler;

    @Override
    public R getSubjectList(Page<Subject> page, String siftClazz, String siftName, String siftId) {
        Page<Subject> list = baseMapper.getSubjectList(page, siftClazz, siftName, siftId);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total", list.getTotal());
        jsonObject.put("list", list.getRecords());
        return R.ok(jsonObject);
    }

    @Override
    public R addSign(Map<String, String> params) {
        String id = params.get("id");
        String subjectId = params.get("subjectId");
        String type = params.get("type");
        int duration = Integer.parseInt(params.get("duration")) * 60;
        String position = params.get("position");
        String code = "";
        if("1".equals(type)) {
            code = params.get("code");
        }
        Date curDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String name = dateFormat.format(curDate) + "签到";
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.SECOND, duration);
        Date endDate = new Date(instance.getTimeInMillis());
        int rs = baseMapper.addSign(id, name, subjectId, type, duration, position, code, curDate, endDate);
        JobDetail jobDetail = JobBuilder
                .newJob(UpdateSignDataTask.class)
                .build();
        jobDetail.getJobDataMap().put("signId", id);
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder
                .simpleSchedule()
                .withIntervalInSeconds(0)
                .withRepeatCount(0);
        SimpleTrigger trigger = TriggerBuilder
                .newTrigger()
                .forJob(jobDetail)
                .startAt(endDate)
                .withSchedule(scheduleBuilder)
                .build();
        try {
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (SchedulerException e) {
            log.error("定时任务执行异常: {}", e);
        }
        return rs > 0 ? R.ok("操作成功") : R.error("操作失败");
    }

    @Override
    public R getSignList(Page<Map<String, String>> page, String id, String type) {
        Page<Map<String, String>> signList = null;
        if("1".equals(type)) {      // 学生可签到课程
            signList = baseMapper.getSignListForStudent(page, id);
        }else {
            signList = baseMapper.getSignList(page, id);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total", signList.getTotal());
        jsonObject.put("list", signList.getRecords());
        return R.ok(jsonObject);
    }

    @Override
    public R getSignRecord(String id) {
        List<Map<String, String>> noSignList = baseMapper.noSignList(id);
        List<Map<String, String>> signList = baseMapper.signList(id);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("noSignList", noSignList);
        jsonObject.put("signList", signList);
        return R.ok(jsonObject);
    }

    @Override
    public R addSignLog(Map<String, String> params) {
        String uid = params.get("uid");
        String signId = params.get("id");
        String img = params.get("img");
        String position = params.get("position");
        String distanceStr = params.get("distance");
        String status = "0";
        String remark = "";
        String signIsExpired = baseMapper.signIsExpired(signId);
        // if(StringUtils.isEmpty(signIsExpired)) {
        //     return R.error("签到失败，签到已结束");
        // }
        if(Integer.parseInt(distanceStr) < 50) {   // 签到位置偏差100m以内属正常范围
            status = "2";
        }else {
            status = "3";
            remark = "签到位置异常";
        }
        String id = UUID.randomUUID().toString().replaceAll("\\-", "");
        int rs = baseMapper.addSignLog(id, signId, uid, img, position, status, remark);
        return rs > 0 ? R.ok("签到成功") : R.error("签到失败");
    }

    @Override
    public R isSigned(String id, String uid) {
        String isSigned = baseMapper.isSigned(id, uid);
        return R.ok(StringUtils.isNotEmpty(isSigned));
    }

    @Override
    public R getSignRecord(Page<Map<String, String>> page, String siftName, String id) {
        Page<Map<String, Object>> list = baseMapper.getSignRecord(page, siftName, id);
        List<Map<String, Object>> rs = new ArrayList<>();
        for(Map<String, Object> map : list.getRecords()) {
            String signId = map.get("id").toString();
            List<Map<String, String>> noSignList = baseMapper.noSignList(signId);
            List<Map<String, String>> signList = baseMapper.signList(signId);
            map.put("noSignList", noSignList);
            map.put("signList", signList);
            rs.add(map);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("total", list.getTotal());
        jsonObject.put("list", rs);
        return R.ok(jsonObject);
    }
}
